package com.tech.langk.testhttps;

/**
 * Created by LangK on 2017/2/4.
 * XUtils框架的https请求
 */


import android.content.Context;
import android.util.Log;

import org.xutils.common.Callback;
import org.xutils.http.HttpMethod;
import org.xutils.http.RequestParams;

import java.io.IOException;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;

import org.xutils.x;

public class HTTPUtil {
    /**
     * Https 证书验证对象
     */
    private static SSLContext s_sSLContext = null;

    /**
     * 客户端证书
     */
    private static String CER_PATH = "client1.p12";
    /**
     * 根证书
     */
    private static String ROOT_CER_PATH = "ca1.crt";
    /**
     * 证书密码
     */
    private static String PassWord = "Dawning2048";
    /**
     * 证书的格式
     * Android仅支持P12 和 BKS格式
     */
    private static String KEY_TYPE = "PKCS12";

    /**
     * Https请求发送
     *
     * @param context  Activity（fragment）的资源上下文
     * @param params   发送的请求
     * @param callBack 回调对象（具体接口形式参见xUtils sample的httpFragment.java）
     * @return true=正常调用 false＝异常调用
     */
    public static boolean send(Context context, RequestParams params, Callback.CommonCallback callBack) {
        /* 判断https证书是否成功验证 */
        SSLContext sslContext = getSSLContext(context);
        if (null == sslContext) {
            if (BuildConfig.DEBUG) Log.d("HttpUtil", "Error:Can't Get SSLContext!");
            return false;
        }
        //绑定SSL证书
        params.setSslSocketFactory(sslContext.getSocketFactory());
        x.http().request(HttpMethod.GET, params, callBack);
        return true;
    }


    /**
     * 获取Https的证书
     *
     * @param context Activity（fragment）的上下文
     * @return SSL的上下文对象
     */
    private static SSLContext getSSLContext(Context context) {
        if (null != s_sSLContext) {
            return s_sSLContext;
        }

        CertificateFactory certificateFactory = null;       //根证书工厂
        KeyStore keystore = null;       //客户端证书的KeyStore
        KeyStore trustKeystore = null;  //根证书信任域的KeyStore
        TrustManagerFactory trustManagerFactory = null; //信任域的管理工厂
        try {
            keystore = KeyStore.getInstance(KEY_TYPE);
            keystore.load(context.getAssets().open(CER_PATH), PassWord.toCharArray());

            KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
            keyManagerFactory.init(keystore, null);

            certificateFactory = CertificateFactory.getInstance("X.509");

            Certificate ca = certificateFactory.generateCertificate(context.getAssets().open(ROOT_CER_PATH));
            trustKeystore = KeyStore.getInstance(KeyStore.getDefaultType());
            trustKeystore.load(null);
            String certificateAlias = Integer.toString(0);
            trustKeystore.setCertificateEntry(certificateAlias, ca);

            trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
            trustManagerFactory.init(trustKeystore);
            TrustManager[] trustManagers =  trustManagerFactory.getTrustManagers();

            // Create an SSLContext that uses our TrustManager
            s_sSLContext = SSLContext.getInstance("TLS");
            s_sSLContext.init(keyManagerFactory.getKeyManagers(),trustManagers, null);
//            X509TrustManager trustManager = new MytmArray();
//            s_sSLContext.init(keyManagerFactory.getKeyManagers(),new X509TrustManager[]{trustManager}, null);
            return s_sSLContext;
        } catch (CertificateException e) {
            e.printStackTrace();
        } catch (KeyManagementException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (KeyStoreException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (UnrecoverableKeyException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 测试代码
     *
     * @throws Exception
     */
    public static void run(Context context) throws Exception {
        String URL = "https://192.168.1.144:10020/account/V1.0.0/login";
        RequestParams params = new RequestParams(URL);
        send(context, params, new Callback.CommonCallback<String>() {

            @Override
            public void onSuccess(String result) {
                Log.d("TAG", result);
            }

            @Override
            public void onError(Throwable ex, boolean isOnCallback) {
                Log.d("TAG", "出错了");
                ex.printStackTrace();
            }

            @Override
            public void onCancelled(CancelledException cex) {

            }

            @Override
            public void onFinished() {

            }
        });
    }

    /**
     * 信任所有主机-对于任何证书都不做检查
     * 弃用
     */
    static class MytmArray implements X509TrustManager {
        public X509Certificate[] getAcceptedIssuers() {
            // return null;
            return new X509Certificate[]{};
        }

        @Override
        public void checkClientTrusted(X509Certificate[] chain, String authType)
                throws CertificateException {
            // TODO Auto-generated method stub

        }

        @Override
        public void checkServerTrusted(X509Certificate[] chain, String authType)
                throws CertificateException {
            // TODO Auto-generated method stub
            // System.out.println("cert: " + chain[0].toString() + ", authType: "
            // + authType);
        }
    }


}